<template>
  <el-dialog title="裁剪头像" :visible.sync="dialogVisible" :show-close="false" :close-on-click-modal="false"
    :close-on-press-escape="false" width="600px" @close="closeDialog">
    <div class="avatar-container">
      <!-- 待上传图片 -->
      <div v-show="!options.img">
        <el-upload ref="upload" class="upload" action="" :on-change="upload" accept="image/png, image/jpeg, image/jpg"
          :show-file-list="false" :auto-upload="false">
          <el-button slot="trigger" ref="uploadBtn" size="small" type="primary">
            选择图片
          </el-button>
        </el-upload>
        <div>支持jpg、png格式的图片，大小不超过5M</div>
      </div>
      <!-- 已上传图片 -->
      <div v-show="options.img" class="avatar-crop">
        <vueCropper v-if="dialogVisible" ref="cropper" class="crop-box" :img="options.img" :auto-crop="options.autoCrop"
          :fixed-box="options.fixedBox" :can-move-box="options.canMoveBox" :auto-crop-width="options.autoCropWidth"
          :auto-crop-height="options.autoCropHeight" :center-box="options.centerBox" :fixed="options.fixed"
          :fixed-number="options.fixedNumber" :can-move="options.canMove" :can-scale="options.canScale" />
      </div>
    </div>
    <span slot="footer" class="dialog-footer">
      <div class="reupload" @click="reupload">
        <span v-show="options.img">重新上传</span>
      </div>
      <div>
        <el-button @click="closeDialog">取 消</el-button>
        <el-button type="primary" @click="getCrop">
          确 定
        </el-button>
      </div>
    </span>
  </el-dialog>
</template>

<script>
import { VueCropper } from 'vue-cropper'
import axios from 'axios'
import { getToken } from '@/utils/auth'
import { getStsApi } from '@/api/upload'
export default {
  name: 'AvatarCropper',
  components: {
    VueCropper
  },
  props: {
    dialogVisible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // vueCropper组件 裁剪配置信息
      options: {
        img: '', // 原图文件
        autoCrop: true, // 默认生成截图框
        fixedBox: false, // 固定截图框大小
        canMoveBox: true, // 截图框可以拖动
        autoCropWidth: 200, // 截图框宽度
        autoCropHeight: 200, // 截图框高度
        fixed: true, // 截图框宽高固定比例
        fixedNumber: [1, 1], // 截图框的宽高比例
        centerBox: true, // 截图框被限制在图片里面
        canMove: false, // 上传图片不允许拖动
        canScale: false // 上传图片不允许滚轮缩放
      },
      // *********oss上传
      stsData: {},
      imageUrl: ''
    }
  },
  created() {
    this.setData()
  },
  methods: {
    // 读取原图
    upload(file) {
      const isIMAGE =
        file.raw.type === 'image/jpeg' || file.raw.type === 'image/png'
      const isLt5M = file.raw.size / 1024 / 1024 < 5
      if (!isIMAGE) {
        this.$message({
          showClose: true,
          message: '请选择 jpg、png 格式的图片',
          type: 'warning'
        })
        return false
      }
      if (!isLt5M) {
        this.$message({
          showClose: true,
          message: '图片大小不能超过 5MB',
          type: 'warning'
        })
        return false
      }
      const reader = new FileReader()
      reader.readAsDataURL(file.raw)
      reader.onload = (e) => {
        this.options.img = e.target.result // base64
      }
    },
    // 获取截图信息
    getCrop() {
      // 获取截图的 base64 数据
      // this.$refs.cropper.getCropData((data) => {
      //   console.log(data)
      // this.$emit('closeAvatarDialog', data)
      // this.closeDialog()
      // })
      // 获取截图的 blob 数据
      this.$refs.cropper.getCropBlob((blob) => {
        // 创建 File 对象
        const file = new File([blob], 'croppedImage.jpg', { type: 'image/jpeg' })
        this.handleUploadImg(file)
        // this.$emit('closeAvatarDialog', data)
        // this.closeDialog()
      })
    },
    // 重新上传
    reupload() {
      this.$refs.uploadBtn.$el.click()
    },
    // 关闭弹框
    closeDialog() {
      this.$emit('update:dialogVisible', false)
      this.options.img = ''
    },
    // *******************上传oss*************
    generateUUID() {
      const timestamp = Date.now().toString(16)
      const random = Math.random().toString(16).slice(2)
      return `${timestamp}${random}`
    },
    setData() {
      getStsApi()
        .then((res) => {
          this.stsData = res.data
        })
        .catch(() => { })
    },
    // 截取上传文件后缀
    getSuffix(filename) {
      const pos = filename.lastIndexOf('.')
      let suffix = ''
      if (pos !== -1) suffix = filename.substring(pos)
      return suffix
    },
    // 上传
    handleUploadImg(file) {
      const that = this
      const signature = this.stsData.mp.signature
      const ossAccessKeyId = this.stsData.body.AccessKeyId
      const policy = this.stsData.mp.policy
      const key =
        this.stsData.file_path +
        this.generateUUID() +
        '.' + this.getSuffix(file.name)
      const securityToken = this.stsData.body.SecurityToken
      const formData = new FormData()
      formData.append('name', file.name) // 文件名称
      formData.append('key', key) // 存储在oss的文件路径
      formData.append('OSSAccessKeyId', ossAccessKeyId) // //accessKeyId
      formData.append('policy', policy) // policy
      formData.append('Signature', signature) // 签名
      formData.append('x-oss-security-token', securityToken) // 使用STS签名时必传。
      formData.append('success_action_status', 200)
      formData.append('file', file, file.name) // 如果是base64文件，那么直接把base64字符串转成blob对象进行上传即可

      return new Promise((resolve, reject) => {
        axios
          .post(that.stsData.host, formData, {
            headers: {
              'Content-Type': 'multipart/form-data',
              'Auth-Token': getToken()
            }
          })
          .then((rep) => {
            // console.log('rep', rep)
            if (rep.status === 200) {
              that.imageUrl = that.stsData.host + '/' + key
              this.$emit('closeAvatarDialog', that.imageUrl)
              this.closeDialog()
            }
            resolve(rep)
          })
          .catch((err) => {
            reject(err)
          })
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 14px;

  .reupload {
    color: #409eff;
    cursor: pointer;
  }
}

.avatar-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 560px;
  height: 400px;
  background-color: #f0f2f5;
  margin-right: 10px;
  border-radius: 4px;

  .upload {
    text-align: center;
    margin-bottom: 24px;
  }

  .avatar-crop {
    width: 560px;
    height: 400px;
    position: relative;

    .crop-box {
      width: 100%;
      height: 100%;
      border-radius: 4px;
      overflow: hidden;
    }
  }
}
</style>
